package business

import (
	"context"
	"encoding/json"
	"github.com/streadway/amqp"
	"golang-manage-admin/lib"
	"golang-manage-admin/providers"
	queueDao "golang-manage-admin/queue/dao"
	"golang-manage-admin/queue/dto"
	"time"
)

type DelayedHandleQueue struct {
	Implementation
}

func (delayedHandle *DelayedHandleQueue) Init() {
	//初始化重试脚本
	delayedHandle.Implementation.Init()
}

/**
 * 配置文件名称
 */
func (delayedHandle *DelayedHandleQueue) GetConfigKey() string {
	return "golang-manage-admin.delayed.handle"
}

/**
 * 队列消费
 */
func (delayedHandle *DelayedHandleQueue) Delivery(ctx context.Context, msg amqp.Delivery) {
	responseMode := ResponseMode{
		ResponseType: "ack",
	}
	defer delayedHandle.Implementation.ReplyQueueHandler(responseMode, msg)

	//发送消息到
	sErr, responseMode := delayedHandle.handleMsg(msg)
	if sErr != nil {
		_ = delayedHandle.logger.Errorf("消息处理失败:%+v", sErr.Error())
		return
	}

	return
}

/**
 * 消息重推
 */
func (delayedHandle *DelayedHandleQueue) handleMsg(msg amqp.Delivery) (error, ResponseMode) {
	form := new(QueueMsgBaseDataForm)
	// @Todo 消息解析
	if err := json.Unmarshal(msg.Body, form); err != nil {
		if string(msg.Body) != "" {
			_ = delayedHandle.logger.Errorf("延时队列--消息解析失败:%s---%s", err.Error(), string(msg.Body))
		}
		return nil, ResponseMode{ResponseType: "ack"}
	}

	delayedHandle.logger.Debugf("延时队列--事件处理接收解析DATA:%+v", form)

	// 延迟处理 -- 数据解析
	delayedHandle.logger.Debugf("延时队列--事件处理接收解析DATA:%+v", form)
	handleData := new(dto.DelayedHandleDataFormIn)
	dataStr := form.Data.(map[string]interface{})
	if err := json.Unmarshal([]byte(dataStr["data"].(string)), handleData); err != nil {
		_ = delayedHandle.logger.Errorf("延时队列--消息解析失败:%s---%s", err.Error(), string(msg.Body))
		return nil, ResponseMode{ResponseType: "ack"}
	}
	if err := handleData.CheckData(); err != nil {
		_ = delayedHandle.logger.Errorf("延时队列--消息校验不通过:%s---%s", err.Error(), string(msg.Body))
		return nil, ResponseMode{ResponseType: "ack"}
	}

	// 延时处理 -- 发生操作
	dealWithTime := time.Now()
	postData := new(dto.DelayedHandelFormOut).SetHandelFormData(handleData.Body)
	response, err := lib.HttpPostValues(handleData.Url, lib.StructToMap(&postData))
	if err != nil {
		_ = delayedHandle.updateTaskInfo(dataStr["task_id"].(string), queueDao.HandleResultFail, err.Error(), dealWithTime)
		_ = delayedHandle.logger.Errorf("系统信息同步失败：%+v，原因：%s", postData, err.Error())
		return nil, ResponseMode{ResponseType: "ack"}
	}

	// 处理完成
	_ = delayedHandle.updateTaskInfo(dataStr["task_id"].(string), queueDao.HandleResultSuccess, string(response), dealWithTime)
	return nil, ResponseMode{ResponseType: "ack"}
}

/**
 *  @Author yang
 *  @Description 更新任务信息
**/
func (delayedHandle *DelayedHandleQueue) updateTaskInfo(taskId string, result int64, responseData string, dealWithTime time.Time) error {
	dao := queueDao.NewDelayedQueueDao()
	tx := providers.Mysqls["task"]
	delayedQueue := queueDao.DelayedQueueTable{
		Result:       result,
		TaskId:       taskId,
		DealWithAt:   dealWithTime,
		DealWithType: queueDao.DealWithTypeQueue,
		ResponseData: responseData,
	}
	_, err := dao.UpdateDelayedQueueInfo(tx, delayedQueue)
	return err
}
